import React, { ReactNode } from 'react';
import { parse } from 'querystring';
import pathRegexp from 'path-to-regexp';
import { Route } from '@/models/connect';
import { QuestionCircleOutlined } from '@ant-design/icons';
import moment from 'moment-timezone';
import { message, notification, Modal } from 'antd';
import { v4 as uuidv4 } from 'uuid';
import * as regex from '@/constants/regex';

/**
 * 获取 uuid
 */
export const getUuid = () => uuidv4();

/**
 * 获取时间段
 * @param h
 */
export const getTimeNameFromHour = (h: number) => {
  if (h >= 6 && h < 9) {
    return '早上';
  }
  if (h >= 9 && h < 12) {
    return '上午';
  }
  if (h >= 12 && h < 14) {
    return '中午';
  }
  if (h >= 12 && h < 19) {
    return '下午';
  }

  return '晚上';
};

/**
 * 将 selectMap 转化为table需要的valueEnum
 * @param selectMap
 */
export const getEnumFromSelectMap = (selectMap: SelectData[]): { [key: string]: string } =>
  selectMap.reduce((prev, cur) => {
    prev[cur.value] = cur.label;
    return prev;
  }, {});

/**
 * 获取基域名
 * @param hostname 需要解析的域名，默认当前域名
 */
export const getBaseHost = (hostname: string = ''): string => {
  hostname = hostname || window.location.hostname;
  if (!/^([^.]+\.){2}[^.]+$/.test(hostname)) {
    return hostname;
  }
  const hostArr = hostname.split('.');
  const baseHost = `.${hostArr.slice(hostArr.length - 2).join('.')}`;
  return baseHost;
};

/**
 * 顶部加载中提示，不阻塞操作
 * @param msg 提示内容
 */
export const msgLoading = (msg: string) => message.loading(msg);

/**
 * toast消息
 * @param msg 需要toast的消息内容
 * @param type 类型：success, warning, error, info, loading，默认success
 */
export const toast = (msg: string, type: string = 'success') => {
  message[type](msg);
};

/**
 * 右上角通知消息
 * @param msg 通知标题
 * @param subMsg 通知描述
 * @param type 类型：success, warning, error, info，默认 success
 */
export const notify = (msg: string, subMsg = '', type = 'success') => {
  notification[type]({
    message: msg,
    description: subMsg,
  });
};

/**
 * alert 消息框
 * @param msg alert 的 消息内容
 * @param type 类型：info, success, warning, error，默认 info
 * @param content 弹窗内容
 * @param cb 确认回调
 */
export const alert = (
  msg: string,
  type = 'info',
  content: string | ReactNode = '',
  cb?: () => void,
) => {
  Modal[type]({
    title: msg,
    content,
    okText: '确定',
    onOK() {
      if (cb) {
        cb();
      }
    },
  });
};

/**
 * 确认弹窗
 * @param msg 提示消息
 * @param ok 确认回调
 * @param cancel 取消回调
 */
export const confirm = (msg: string, ok?: () => void, cancel?: () => void, content?: string) => {
  Modal.confirm({
    title: msg,
    icon: <QuestionCircleOutlined />,
    content,
    onOk() {
      if (ok) {
        ok();
      }
    },
    onCancel() {
      if (cancel) {
        cancel();
      }
    },
  });
};

/**
 * 格式化日期
 * @param value
 * @param formatStr 1=>YYYY-MM-DD HH:mm:ss, 2=>YYYY-MM-DD
 * @param timeZone true=>Asia/Shanghai
 */
export const formatDate = (
  value: any,
  formatStr: string | number = 1,
  timeZone: string | boolean = '',
) => {
  if (!value) {
    return '';
  }

  let date = moment(value);
  if (!date.isValid()) {
    return '';
  }
  if (timeZone === true) {
    timeZone = 'Asia/Shanghai';
  }
  if (timeZone) {
    date = date.tz(timeZone);
  }

  let targetFormatStr: string | undefined;
  if (formatStr === 1) {
    targetFormatStr = 'YYYY-MM-DD HH:mm:ss';
  } else if (formatStr === 2) {
    targetFormatStr = 'YYYY-MM-DD';
  } else if (typeof formatStr === 'string' && formatStr) {
    targetFormatStr = formatStr;
  }

  if (date.isValid()) {
    return date.format(targetFormatStr);
  }
  return '';
};

/**
 * 把html字符串格式化：\n、\t、\"
 * @param html html文本
 */
export function getHtml(html: string | object) {
  const content = typeof html === 'string' ? html : JSON.stringify(html, null, '\t');
  if (!content) {
    return '';
  }
  const r = content
    .replace(/\n|\\n/g, '<br>')
    .replace(/\t/g, '&nbsp;')
    .replace(/\\"/g, '')
    .replace(/,/g, ',&nbsp;');
  return r;
}

/**
 * 解码url
 * @param url 路径
 */
export function decodeUrl(url: string) {
  let targetUrl = url;

  try {
    // eslint-disable-next-line no-plusplus
    for (let i = 0; i < 10; i++) {
      targetUrl = decodeURI(targetUrl);
    }
  } catch (e) {
    console.log(e);
  }

  return targetUrl;
}

/**
 * 获取文件名字
 * @param path 路径
 */
export function getFileName(path: string) {
  if (!path) {
    return '';
  }

  const index = path.lastIndexOf('/');
  if (index < 0) {
    return path;
  }

  return path.substr(index + 1);
}

export const isUrl = (path: string): boolean => regex.url.test(path);

export const isAntDesignPro = (): boolean => {
  if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
    return true;
  }
  return window.location.hostname === 'preview.pro.ant.design';
};

// 给官方演示站点用，用于关闭真实开发环境不需要使用的特性
export const isAntDesignProOrDev = (): boolean => {
  const { NODE_ENV } = process.env;
  if (NODE_ENV === 'development') {
    return true;
  }
  return isAntDesignPro();
};

export const getPageQuery = () => parse(window.location.href.split('?')[1]);

/**
 * props.route.routes
 * @param router [{}]
 * @param pathname string
 */
export const getAuthorityFromRouter = <T extends { path?: string }>(
  router: T[] = [],
  pathname: string,
): T | undefined => {
  const authority = router.find(({ path }) => path && pathRegexp(path).exec(pathname));
  if (authority) return authority;
  return undefined;
};

export const getRouteAuthority = (path: string, routeData: Route[]) => {
  let authorities: string[] | string | undefined;
  routeData.forEach(route => {
    // match prefix
    if (pathRegexp(`${route.path}/(.*)`).test(`${path}/`)) {
      if (route.authority) {
        authorities = route.authority;
      }
      // exact match
      if (route.path === path) {
        authorities = route.authority || authorities;
      }
      // get children authority recursively
      if (route.routes) {
        authorities = getRouteAuthority(path, route.routes) || authorities;
      }
    }
  });
  return authorities;
};
